﻿using System;
using Sencha.Serialization.Contracts;

namespace Sencha.Serialization
{

	public abstract class TypeSerializer<SerializedType> : ITypeSerializer
	{
		protected virtual TypeDescription TypeDescription { get; set; }

		public abstract SerializedType Deserialize(IJsonReader reader);
		public abstract void Serialize(IJsonWriter writer, SerializedType value);

		#region ITypeSerializer Members

		TypeDescription ITypeSerializer.SerializedType { get { return this.TypeDescription; } }

		object ITypeSerializer.Deserialize(IJsonReader reader)
		{
			if (reader == null)
				throw new ArgumentNullException("reader");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			if (reader.Token == JsonToken.Null)
				return null;

			return this.Deserialize(reader);
		}

		public void Serialize(IJsonWriter writer, object value)
		{
			if (writer == null)
				throw new ArgumentNullException("writer");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			if (value == null)
			{
				writer.Write(JsonToken.Null);
				return;
			}

			this.Serialize(writer, (SerializedType)value);
		}

		#endregion
	}

	interface ITypeSerializer
	{
		TypeDescription SerializedType { get; }

		object Deserialize(IJsonReader reader);
		void Serialize(IJsonWriter writer, object value);
	}
}
